#!/usr/bin/env python
# -*- coding: utf-8 -*-
# We require the srvrmgrdIO module to prepare the request and talk to servermgrd
# Also require python plistlib library (apt-get install python-plistlib [in Debian/Ubuntu])
# http://svn.python.org/projects/python/trunk/Lib/plistlib.py
#
#
#    Copyright (C) 2010 - 2011 Felim Whiteley
#
#    Author: Felim Whiteley <felimwhiteley@gmail.com>
#             http://www.linkedin.com/in/felimwhiteley
#	      http://whiteleytech.ie
#
#    Version: 0.6.2
#
#    This is free software; you can redistribute it and/or modify it
#    under the terms of the GNU Lesser General Public License as
#    published by the Free Software Foundation; version 3 of
#    the License, or any later version.
#
#    This software is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#    Lesser General Public License for more details.
#
#    You should have received a copy of the GNU Lesser General Public
#    License along with this software; if not, write to the Free
#    Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
#    02110-1301 USA, or see the FSF site: http://www.fsf.org.


import pickle, srvrmgrdIO, subprocess, sys, time

configINI = '/etc/libServerManagerDaemon.ini'

# Default to NOT using datafile in /tmp for shareable data;
# If set config file then check set value for dataFileMode
dataFileMode = 0
# Default To Hiding SubService Results When Ignored
showDisabledSubServices = 0

# Debug Logging
def logMessage(serverMessage, serverAddress, serverPort):
	try:
		logFileLocation = "/tmp/%s_%s.debug" % (serverAddress, serverPort)
		logFile = open(logFileLocation, "a")
		#print "%s: %s" % (time.strftime("%Y-%m-%d %H:%M:%S"), serverMessage)
		logFile.write("%s: %s\n" % (time.strftime("%Y-%m-%d %H:%M:%S"), serverMessage))
		logFile.flush()
		logFile.close()
	except:
		print "DEBUG_LOG_ERROR: %s" % (sys.exc_info()[1])

# CLI Debug Switch
debugMode = 0
testMode = 0
if len(sys.argv) > 1:
	if sys.argv[1] == "DEBUG":
		debugMode = 1
	elif sys.argv[1] == "TEST":
		testMode = 1
		debugMode = 1

# Module Configuration
osxServices = {
	'afp': ['currentConnections'],
	'calendar': [],
	'dhcp': ['numDHCPLeases', 'numConfiguredStaticMaps', 'timeOfSnapShot', 'numActiveStaticMaps'],
	'dirserv': ['timState', 'ldapdState', 'kdcStatus', 'lookupdState', 'passwordServiceState', 'netinfodState', 'netinfodParentState'],
	'dns': ['zonesAllocated', 'SOAQueriesInProgress', 'transfersRunning', 'transfersDeferred'],
	'ftp': ['realConnectionCount', 'anonymousAccessPermitted', 'anonymousConnectionCount'],
	'ipfilter': [],
	'jabber': ['serviceMode', 'jabberdState', 'mucState', 'proxyState'],
	'mysql': ['currentConnections', 'currentThroughput'],
	'nat': ['activeICMP', 'activeTCP', 'activeUDP'],
	'netboot': [],
	'nfs': ['nsfd', 'mountd', 'portmap', 'rpc.lockd'],
	'pcast': ['onlineCameras', 'totalCameras', 'currentJobs', 'totalJobs'],
	'print': ['currentJobs', 'currentQueues'],
	'qtss': ['stateAFP', 'stateDHCP', 'stateHTTP', 'stateNFS', 'stateTFTP'],
	'radius': [],
	'smb': ['currentConnections'],
	'swupdate': ['numOfMirroredPkg', 'numOfEnbabledPkg'],
	'teams': [],
	'vpn': [],
	'web': ['apacheState', 'proxyState', 'totalKBytes', 'totalRequests'],
	'webobjects': [],
	'xgrid': {'agentStatus': ['status', 'activeCPUPower'], 'controllerStatus': ['status', 'workingCPUPower']}
}

def convertListToCsv(pythonList, sqlMode=0):
        csvString = ''
        for listItem in pythonList:
                if csvString == '':
			if sqlMode:
				csvString = "'%s'" % listItem
			else:
				csvString = "%s" % listItem
                else:
			if sqlMode:
				csvString = "%s,'%s'" % (csvString, listItem)
			else:
				csvString = "%s,%s" % (csvString, listItem)
        return csvString

# Load Config File If Available
configDebugMessage = ''
try:
	import ConfigParser
	config = ConfigParser.ConfigParser()
	config.readfp(open(configINI))
	try:
		dataFileMode = int(config.get("config", "dataFileMode"))
	except:
		pass
	try:
		showDisabledSubServices = int(config.get("config", "showDisabledSubServices"))
	except:
		pass
	configDebugMessage = "DEBUG: %s Found: dataFileMode:%s" % (configINI, dataFileMode)
except:
	configDebugMessage = "ERROR: %s Not Found Or Invalid" % (configINI)

if len(sys.argv) >= 6:
	# If We Are Running In Debug Then Shift The Position Of All Variables
	checkService = sys.argv[1 + debugMode]
	serverAddress = sys.argv[2 + debugMode]
	serverPort = sys.argv[3 + debugMode]
	serverUser = sys.argv[4 + debugMode]
	serverPassword = sys.argv[5 + debugMode]
	# Ignore List For subServices
	if len(sys.argv) > (6 + debugMode):
		subServiceIgnoreCSV = sys.argv[6 + debugMode]
		subServiceIgnore = subServiceIgnoreCSV.split(',')
	else:
		subServiceIgnore = []
	if debugMode:
		if configDebugMessage:
			# Send Config Parse Message to Log
			logMessage(configDebugMessage, serverAddress, serverPort)
		try:
			# Send System Args To Log
			logMessage(sys.argv, serverAddress, serverPort)
			# Send List Of Files Belonging To This Server
			tempDirList = subprocess.Popen('ls -l /tmp/%s*' % (serverAddress), shell=True, stdout=subprocess.PIPE).stdout
			tempDirListing = tempDirList.readlines()
			tempData = ''
			for fileFound in tempDirListing:
				tempData += fileFound
			tempData = "Files In /etc\n%s" % (tempData)
			logMessage(tempData, serverAddress, serverPort)
		except:
			print "DEBUG_ERROR: %s" % (sys.exc_info()[1])
else:
	print "OS X Server Monitoring Tool\n\tVersion: 0.6.2"
	print "\tCopyright (C) 2010 - 2011 Felim Whiteley"
	print "\thttp://whiteleytech.ie"
	print "\thttp://code.google.com/p/libsrvrmgrd-osx/"
	print "This software is licensed under the GNU Lesser General Public License\n"
	print "USAGE: check_osx_server SERVICENAME ADDRESS PORT USER PASSWORD [Optional Sub-Service Ignore List]"
	print "\t--------\t------------"
	print "\tServices\tSub-Services"
	print "\t--------\t------------"
	for serviceName, subServiceList in osxServices.iteritems():
		if len(serviceName) > 7:
			txtTabs = "\t"
		else:
			txtTabs = "\t\t"
		if isinstance(subServiceList, dict):
			print "\t%s%s%s" % (serviceName, txtTabs, convertListToCsv(subServiceList.keys()))
		elif len(subServiceList) == 0:
			noSubServices = "--NO SUB-SERVICES AVAILABLE--"
			print "\t%s%s%s" % (serviceName, txtTabs, noSubServices)
		else:
			print "\t%s%s%s" % (serviceName, txtTabs, convertListToCsv(subServiceList))
	print "\tsoftwareupdates\t--NO SUB-SERVICES AVAILABLE--"
	print "\nWhen adding Sub-Service ignore values they should be the last argument, seperated by commas and contain no whitespace"
	print "\nEXAMPLE: check_osx_server jabber 172.16.12.1 311 srvadmin srvpassword mucState,proxyState\n"
	print "\tmucState & proxyState will be ignored and will not trigger a warning\n"
	print "-----------"
	print "System Load"
	print "-----------"
	print "USAGE: check_osx_server SYSTEMSTAT ADDRESS PORT USER PASSWORD WARN_THRESHOLD CRIT_THRESHOLD"
	print "\nSYSTEMSTAT:"
	print "\tcpuUsage\t\tView Percentage Of Aggregated CPU(s) & Cores Used"
	print "\tnetUsage\t\tView The Overall Kilobits/Second Network Usage"
	print "\thddUsage\t\tView Percentage Of HDD Used On All Drives"
	print "\tsysUsage\t\tCombined View Of All Of The Above\n"
	print "\t\tThe WARN_THRESHOLD & CRIT_THRESHOLD are optional and default to 80% & 90% respectivly"
	print "\t\t(If you do use your own values you must use both or it will trigger an error) \n"
	print "------------------"
	print "Informational Mode"
	print "------------------"
	print "USAGE: check_osx_server INFOMODE ADDRESS PORT USER PASSWORD"
	print "\nINFOMODES:"
	print "\tafpUserList\t\tView User(s) Connected Via AFP"
	print "\tsmbUserList\t\tView User(s) Connected Via SMB"
	print "\tserverRole\t\tList The Roles & Service Configured"
	print "\tsoftwareupdatesList\tList All Updates Required By The Server"
	print ""
	sys.exit(0)

warningCount = 0
criticalCount = 0
unknownCount = 0

def getServiceData(servermgrdModule, dataReqCommand, dataReqVariant=None, dataReqTimescale=None, dataReqIdentifier=None, dataReqOffset=None, dataReqAmount=None):
	# TEST Mode - This will be moving somewhere else
	if testMode:
		if servermgrdModule == "servermgr_xgrid":
			# XGrid test Data
			serviceData = {'servicePortsAreRestricted': 'NO', 'servicePortsRestrictionInfo': [], 'state': 'RUNNING', 'readWriteSettingsVersion': 1, 'startedTime': '', 'setStateVersion': 1, 'command': 'getState', 'controllerStatus': {'status': 'OK', 'workingCPUPower': '5'}, 'logPaths': {'xgridSystemLog': '/var/log/system.log', 'xgridAgentLog': '/Library/Logs/Xgrid/xgridagentd.log', 'xgridControllerLog': '/Library/Logs/Xgrid/xgridcontrollerd.log'}, 'agentStatus': {'status': 'STOPPED', 'activeCPUPower': '1'}}
			return serviceData
		else:
			print "TEST NOT AVAILABLE: '%s'" % servermgrdModule
			sys.exit(0)
	# buildXML ( command, variant=None, timescale=None, identifier=None, offset=None, amount=None )
	dataRequest = srvrmgrdIO.buildXML(dataReqCommand, dataReqVariant, dataReqTimescale, dataReqIdentifier, dataReqOffset, dataReqAmount)
	if debugMode:
		serverMessage = "#### REQUEST ####\n%s\n #### END REQUEST ####\n" % (dataRequest)
		logMessage(serverMessage, serverAddress, serverPort)
		serverMessage = "VARIABLES: [%s]\n servermgrdModule = '%s'\n serverAddress = '%s'\n serverPort  = '%s'\n serverUser = '%s'\n serverPassword = '%s'" % (len(sys.argv), servermgrdModule, serverAddress, serverPort, serverUser, serverPassword)
		logMessage(serverMessage, serverAddress, serverPort)
	if dataFileMode:
		# Store Data In /tmp
		dataFileLocation = srvrmgrdIO.buildDataFile(servermgrdModule, dataRequest, serverAddress, serverPort, serverUser, serverPassword, debugMode)
		dataFile = open(dataFileLocation, "rb")
		serviceData = pickle.load(dataFile)
		dataFile.close()
	else:
		# Dont Store Data In /tmp
		serviceData = srvrmgrdIO.sendXML(servermgrdModule, dataRequest, serverAddress, serverPort, serverUser, serverPassword)
	return serviceData

def getServiceState(serviceData):
	# Set some intial values
	serviceStatus = ""
	criticalCount = 0
	serviceState = serviceData['state']
	if 'state' in serviceData:
		if serviceState == 'RUNNING':
			serviceStatus = "%s" % (serviceState)
		else :
				criticalCount += 1
				serviceStatus = "%s" % (serviceState)
	else:
		serviceStatus = "UNKNOWN: Invalid Data Returned From Service Check"
		criticalCount += 1
	return serviceStatus, criticalCount

def getServiceThreshold(sensorReading, warnLevel=80, critLevel=90):
	warningCount = 0
	criticalCount = 0
	if warnLevel < critLevel:
		# For Processor/Mem Usage Where We Have An Upper Limit
		if sensorReading >= critLevel:
			criticalCount += 1
		elif sensorReading >= warnLevel:
			warningCount += 1
	elif warnLevel > critLevel:
		# Where We Want To Be Warned When They Run Out Of Resouce ie. Lower Limit
		if sensorReading <= critLevel:
			criticalCount += 1
		elif sensorReading <= warnLevel:
			warningCount += 1
	else:
		# Stop Folk Setting Warn & Crit To Same Value... ;)
		print "ERROR: Warning & Critical Levels Are The Same"
		sys.exit(1)
	return warningCount, criticalCount

def getSubServiceState(subServices, serviceData, subServiceIgnore):
	warningCount = 0
	subServiceStatus = ""
	# Some Services Use Sub-Arrays Within The PList - We need to handle a Sub-SubService
	# Effectivly: This is rather ugly and should really change this!
	if isinstance(subServices, dict):
		for subServiceName, subServiceArray in subServices.iteritems():
			if subServiceName in serviceData:
				subServiceInfo = ''
				for subServiceItem in subServiceArray:
					# Default to Showing Sub Services In Output
					displaySubService = 1
					if subServiceItem in serviceData[subServiceName].keys():
						subServiceState = serviceData[subServiceName][subServiceItem]
						# Are we tracking Sub Service Warnings For This Sub Service
						if subServiceName not in subServiceIgnore:
							# Need to strip out possible float values - This is very hackish
							if not str(subServiceState).replace('.', '').isdigit():
								if subServiceState.upper() in ('UNAVAILABLE', 'STOPPED', 'OFF'):
									warningCount += 1
						else:
							# A Sub Service We Want To Ignore
							if not showDisabledSubServices:
								# Are We Globally Showing Disabled Subservices
								displaySubService = 0
						if displaySubService:
							if subServiceInfo == '':
								subServiceInfo = "[%s%s:%s " % (subServiceInfo, subServiceItem, serviceData[subServiceName][subServiceItem])
							else:
								subServiceInfo = "%s%s:%s " % (subServiceInfo, subServiceItem, serviceData[subServiceName][subServiceItem])
				if subServiceInfo != '':
					subServiceStatus = "%s%s:%s] " % (subServiceStatus, subServiceName, subServiceInfo.rstrip())
	# Normal Sub-Services
	else:
		for subService in subServices:
			# Default to Showing Sub Services In Output
			displaySubService = 1
			if subService in serviceData:
				subServiceState = serviceData[subService]
				if subService not in subServiceIgnore:
					# Need to strip out possible float values - This is very hackish
					if not str(subServiceState).replace('.', '').isdigit():
						if subServiceState.upper() in ('STOPPED', 'OFF'):
							warningCount += 1
				else:
					# Ignoring SubServices
					# Are We Showing Them?
					if not showDisabledSubServices:
						displaySubService = 0
				if displaySubService:
					subServiceStatus = "%s%s:%s " % (subServiceStatus, subService, subServiceState)
	return subServiceStatus, warningCount

# Process The Service
if checkService in ('afpUserList', 'smbUserList'):
	dataReqCommand = 'getConnectedUsers'
	# Strip First 3 Characters To Run Against Correct OSX Module
	serviceData = getServiceData('servermgr_%s' % (checkService[:3]), dataReqCommand, 'withDetails')
	serviceStatus, criticalCount = getServiceState(serviceData)
	if not criticalCount:
		userCount = 0
		userList = "%s Connections Active\n" % (checkService[:3].upper())
		for userConnection in serviceData['usersArray'] :
			userCount += 1
			userList = "%s\t%s:\t%s\n" % (userList, userConnection['ipAddress'], userConnection['name'])
		if userCount:
			print userList
		serviceStatus = "Connections:%s" % (userCount)
elif checkService in ('sysUsage', 'cpuUsage', 'hddUsage', 'netUsage'):
	dataReqCommand = 'getHardwareInfo'
	serviceData = getServiceData('servermgr_info', dataReqCommand, '')
	serviceStatus = ''
	warnLevel = None
	critLevel = None
	warningCountMaster = 0
	criticalCountMaster = 0
	# It's optional to provide the thresholds but must provide both if you do
	if len(sys.argv) > (6 + debugMode):
		# Must Have Both Warn And Crit Set
		if len(sys.argv) == (8 + debugMode):
			warnLevel = int(sys.argv[6 + debugMode])
			critLevel = int(sys.argv[7 + debugMode])
		else:
			print "ERROR: Incorrect Number Of Arguments"
			sys.exit(1)
	if checkService in ('sysUsage', 'cpuUsage'):
		sensorReading = int(serviceData['cpuUsageBy100']/100)
		if warnLevel and critLevel:
			warningCount, criticalCount = getServiceThreshold(sensorReading, warnLevel, critLevel)
		else:
			warningCount, criticalCount = getServiceThreshold(sensorReading)
		warningCountMaster += warningCount
		criticalCountMaster += criticalCount
		serviceStatus += "cpuUsage:%s%% " % (sensorReading)
	if checkService in ('sysUsage', 'netUsage'):
		sensorReading = int(serviceData['networkThroughputBy1K'])
		# If no threshold set then we don't check becasue no precentage calculation possible with network
		if warnLevel and critLevel:
			warningCount, criticalCount = getServiceThreshold(sensorReading, warnLevel, critLevel)
		warningCountMaster += warningCount
		criticalCountMaster += criticalCount
		serviceStatus += "netUsage:%skb/s " % (sensorReading)
	if checkService in ('sysUsage', 'hddUsage'):
		hddStatus = ""
		for hddInfo in serviceData['volumeInfosArray']:
			hddName = hddInfo['name']
			totalBytes = float(hddInfo['totalBytes'])
			freeBytes = float(hddInfo['freeBytes'])
			usedBytes = float(totalBytes-freeBytes)
			hddUsagePercentage = int((usedBytes/totalBytes) * 100)
			# If Thresholds Are Set Check If Lower Than 100 - Assume Percentage, Otherwise Actual Bytes
			hddStatus += "'%s':%s%% " % (hddName, hddUsagePercentage)
			if warnLevel and warnLevel <= 100:
				warningCount, criticalCount = getServiceThreshold(hddUsagePercentage, warnLevel, critLevel)
				warningCountMaster += warningCount
				criticalCountMaster += criticalCount
			elif warnLevel and warnLevel > 100:
				warningCount, criticalCount = getServiceThreshold(hddUsagePercentage, warnLevel, critLevel)
				warningCountMaster += warningCount
				criticalCountMaster += criticalCount
		serviceStatus += "hddUsage:[%s] " % (hddStatus.rstrip())
	warningCount = warningCountMaster
	criticalCount = criticalCountMaster
elif checkService == "mail":
	serviceData = getServiceData('servermgr_mail', 'getState', 'withDetails')
	serviceStatus, criticalCount = getServiceState(serviceData)
	if not criticalCount:
		serviceStatus = "%s " % (serviceStatus) # Keep Initial RUNNING
		# Example Of Data Returned
		# {'active': 0, 'status': 'OFF', 'kind': 'INCOMING', 'total': 0, 'protocol': 'SMTP'}
		# {'active': 0, 'status': 'OFF', 'kind': 'OUTGOING', 'total': 0, 'protocol': 'SMTP'}
		# {'active': 0, 'status': 'OFF', 'kind': 'INCOMING', 'total': 0, 'protocol': 'POP3'}
		# {'active': 0, 'status': 'OFF', 'kind': 'INCOMING', 'total': 0, 'protocol': 'IMAP'}
		# {'active': 0, 'status': 'OFF', 'kind': 'INCOMING', 'total': 0, 'protocol': 'LISTSERVER'}
		for protocol in serviceData['protocolsArray']:
			name = protocol['protocol']
			kind = protocol['kind']
			total = protocol['total']
			active = protocol['active']
			status = protocol['status']
			if status == 'ON' :
				serviceStatus = "%s%s-%s:Act(%s)Total(%s) " % (serviceStatus, name, kind, active, total)
			else :
				serviceStatus = "%s%s-%s:(%s) " % (serviceStatus, name, kind, status)
elif checkService in ("softwareupdates", "softwareupdatesList"):
	patchList = []
	normalPatches = 0
	recommendedPatches = 0
	restartRequired = 0
	serviceData = getServiceData('servermgr_info', 'getSWUpdateStatus')
	if 'swupdateStatus' in serviceData:
		if 'phaseResultsArray' in serviceData['swupdateStatus']:
			for softwareUpdate in serviceData['swupdateStatus']['phaseResultsArray']:
				if softwareUpdate['ignored']: # ie. Ignored Is True - Meaning Don't Ignore!
					normalPatches += 1
					warningCount += 1
				else:
					recommendedPatches += 1
					criticalCount += 1
				if softwareUpdate['restartRequired'] == 'YES':
					restartRequired += 1
				patchList.append({'swPatch': softwareUpdate['ignoreKey'], 'patchName': softwareUpdate['name'], 'sizeInKB': softwareUpdate['sizeInKB'], 'restartRequired':softwareUpdate['restartRequired'], 'productKey': softwareUpdate['productKey']})
		serviceStatus = "totalPatches:%s" % (normalPatches + recommendedPatches)
		if recommendedPatches:
			serviceStatus = "%s recommendedPatches:%s" % (serviceStatus, recommendedPatches)
		if restartRequired:
			serviceStatus = "%s restartRequired" % (serviceStatus)
		if checkService == 'softwareupdatesList':
			for swPatch in patchList:
				restartStatus = ""
				if swPatch['restartRequired'] == 'YES':
					restartStatus = " : [RESTART]"
				print "%s : %skB : [%s]%s" % (swPatch['swPatch'], swPatch['sizeInKB'], swPatch['productKey'], restartStatus)
	else:
		unknownCount += 1
elif checkService == "serverRole":
	serviceData = getServiceData('servermgr_info', 'getState', 'withDetails')
	if 'serviceConfig' in serviceData:
		if 'roles' in serviceData['serviceConfig']:
			serviceStatus = "Server Role(s):\n"
			for serverRole, serverRoleStatus in serviceData['serviceConfig']['roles'].iteritems():
				if serverRoleStatus['configured']:
					serviceStatus = "%s\t%s\n" % (serviceStatus, serverRole)
		if 'services' in serviceData['serviceConfig']:
			serviceStatus = "%sActive Services:\n" % (serviceStatus)
			for serviceName, serviceNameStatus in serviceData['serviceConfig']['services'].iteritems():
				if serviceNameStatus['configured']:
					serviceStatus = "%s\t%s\n" % (serviceStatus, serviceName)
	serviceStatus.rstrip('\n')
elif checkService in osxServices:
	serviceData = getServiceData('servermgr_%s' % checkService, 'getState', 'withDetails')
	serviceStatus, criticalCount = getServiceState(serviceData)
	subServices = osxServices[checkService]
	if not criticalCount:
		# Not All Services Have Sub-Services
		if len(subServices) > 0:
			subServiceStatus, warningCount = getSubServiceState(subServices, serviceData, subServiceIgnore)
			# Some services have sub-services that are not always there
			# if they are there then return the sub-services-status instead
			if subServiceStatus not in (None, ''):
				serviceStatus = subServiceStatus
else:
	unknownCount = 1
	serviceStatus = "ERROR:Unknown command '%s'" % (checkService)

# If In Debug Mode Print Out The Returned Dictionary So Can Check Values etc.
if debugMode:
	serverMessage = serviceData
	logMessage(serverMessage, serverAddress, serverPort)
	serverMessage = "unknownCount: %s\nwarningCount: %s\ncriticalCount: %s" % (unknownCount, warningCount, criticalCount)
	logMessage(serverMessage, serverAddress, serverPort)
	serverMessage = "serviceStatus: '%s'" % serviceStatus
	logMessage(serverMessage, serverAddress, serverPort)
# End Checks Print Status Message And Exit With Correct Exit Code
# Nagios Return Codes
# 0 - OK
# 1 - Warning
# 2 - Critical
# 3 - Unknown (Invalid command line arguments were supplied to the plugin or
#              low-level failures internal to the plugin (such as unable to
#              fork, or open a tcp socket) that prevent it from performing the
#              specified operation. Higher-level errors (such as name resolution
#              errors, socket timeouts, etc) are outside of the control of
#              plugins and should generally NOT be reported as UNKNOWN states.)
print serviceStatus
if unknownCount:
        sys.exit(3)
elif criticalCount:
        sys.exit(2)
elif warningCount:
	sys.exit(1)
else :
        sys.exit(0)
